import React, { Component } from 'react'
import { Button, message, Spin } from 'antd'
import AddSingleChoice from './AddSingleChoice'
import AddMultipleChoice from './AddMultipleChoice'
import AddFillInBlank from './AddFillInBlank'
import BaseTemplate from './BaseTemplate'
import './Middle.less'
import XLSX from 'xlsx'

const dataIndexMap = {
    "题型": "type",
    "题目": "questionContext",
    "参考答案": "trueAnswer",
    "选项": "options",
    "分数": "score"
}

class Index extends Component {

    constructor(props) {
        super(props)
        this.state = {
            questionList: [],
            dealAmount: 0
        }
        this.save = this.save.bind(this)
        this.deleted = this.deleted.bind(this)
        this.changeType = this.changeType.bind(this)
        this.updateFullScore = this.updateFullScore.bind(this)
        this.importFromExcel = this.importFromExcel.bind(this)
    }

    save(question, index) {
        const nextQuestionList = JSON.parse(JSON.stringify({ data: this.state.questionList })).data
        nextQuestionList[index] = {
            ...nextQuestionList[index],
            ...question
        }
        this.setState({
            questionList: nextQuestionList
        }, () => {
            this.updateFullScore()
            console.log(this.state.questionList)
        })
    }

    deleted(index) {
        const nextQuestionList = JSON.parse(JSON.stringify({ data: this.state.questionList })).data
        nextQuestionList.splice(index, 1)
        this.setState({
            questionList: nextQuestionList
        }, () => {
            this.updateFullScore()
            console.log(this.state.questionList)
        })
    }

    changeType(type, score, index) {
        const nextQuestionList = JSON.parse(JSON.stringify({ data: this.state.questionList })).data
        let { trueAnswer } = nextQuestionList[index]
        if (type !== nextQuestionList[index].type) {
            trueAnswer = undefined
        }
        nextQuestionList[index] = {
            ...nextQuestionList[index],
            type, score, trueAnswer
        }
        this.setState({
            questionList: nextQuestionList
        }, () => {
            this.updateFullScore()
            console.log(this.state.questionList)
        })
    }

    checkQuestion(questionList) {
        let flag = true
        if (questionList instanceof Array && questionList.length > 0) {
            for (let index = 0; index < questionList.length && flag; index += 1) {
                const question = questionList[index]
                const { type } = question
                const { score, questionContext, trueAnswer, options } = question
                console.log(question)
                console.log({ score, questionContext, trueAnswer, options })
                switch (type) {
                    case "singleChoice": {
                        if (!score || isNaN(score) || score < 0) {
                            flag = false
                        }
                        if (!questionContext?.trim?.()) { flag = false }
                        if (!trueAnswer) { flag = false }
                        if (!options) { flag = false } else {
                            if (options instanceof Array && options.length > 0) {
                                options.forEach((option) => {
                                    if (!option?.trim?.()) {
                                        flag = false
                                    }
                                })
                            } else {
                                flag = false
                            }
                        }
                        break;
                    }
                    case "multipleChoice": {
                        if (!score || isNaN(score) || score < 0) {
                            flag = false
                        }
                        if (!questionContext?.trim?.()) { flag = false }
                        if (!(trueAnswer instanceof Array && trueAnswer.length > 0)) { flag = false }
                        if (!options) { flag = false } else {
                            if (options instanceof Array && options.length > 0) {
                                options.forEach((option) => {
                                    if (!option?.trim?.()) {
                                        flag = false
                                    }
                                })
                            } else {
                                flag = false
                            }
                        }
                        break;
                    }
                    case "fillInBlank": {
                        if (!score || isNaN(score) || score < 0) {
                            flag = false
                        }
                        if (!questionContext?.trim?.()) { flag = false }
                        if (!trueAnswer) { flag = false } else {
                            if (trueAnswer instanceof Array && trueAnswer.length > 0) {
                                trueAnswer.forEach((answer) => {
                                    if (!answer?.trim?.()) {
                                        flag = false
                                    }
                                })
                            } else {
                                flag = false
                            }
                        }
                        break;
                    }
                    default: break
                }
                if (!flag) {
                    const ele = document.getElementsByClassName(`Q${index}`)[0]
                    const style = ele.getAttribute("style")
                    message.warn("有题目未填写完整,或数据不符合规范")
                    ele.scrollIntoView({
                        behavior: 'smooth'
                    })
                    ele.setAttribute("style", `${style}border:1px solid red;`)
                    setTimeout(() => {
                        ele.setAttribute("style", `${style}`)
                    }, 2000)
                }
            }
        } else {
            flag = false
            message.warn("至少需要一道题目")
        }
        return flag
    }

    updateFullScore() {
        const { questionList } = this.state
        let fullScore = 0
        questionList.forEach((q) => {
            fullScore += q.score
        })
        this.props.getFullScore(fullScore)
    }

    async importFromExcel(dataList) {
        const preLength = this.state.questionList.length
        const newQuestionList = []
        let successAmount = 0
        let errorAmount = 0
        if (dataList instanceof Array) {
            dataList.forEach((data, index) => {
                const { type, questionContext, trueAnswer, options, score } = data
                let newQuestion = {}
                switch (type) {
                    case '单选题': {
                        successAmount += 1
                        newQuestion = {
                            type: "singleChoice",
                            id: `${new Date().getTime() + index}`,
                            questionContext,
                        }
                        let optionList = []
                        if (typeof options === "string") {
                            optionList = options.split("\n")
                        } else {
                            optionList = `${options}`.split("\n")
                        }
                        newQuestion.options = optionList
                        const optionLength = optionList.length
                        const reg = new RegExp(`[A-${String.fromCharCode(65 + optionLength - 1)}]`, "g")
                        let flag = true
                        if (typeof trueAnswer === "string") {
                            if (trueAnswer.length === 1) {
                                if (reg.test(trueAnswer)) {
                                } else {
                                    flag = false
                                }
                            } else {
                                flag = false
                            }
                        } else {
                            flag = false
                        }

                        if (flag) {
                            newQuestion.trueAnswer = trueAnswer
                        } else {
                            newQuestion.trueAnswer = "A"
                            const index = preLength + successAmount
                            this.setState({
                                dealAmount: this.state.dealAmount + 1
                            }, () => {
                                console.log(this.state.dealAmount)
                            })
                            message.warn({
                                key: `Q${index}`,
                                duration: 0,
                                content: `第${index}题参考答案不符合规范，已重置为A选项，点击查看`,
                                onClick: () => {
                                    this.setState({
                                        dealAmount: this.state.dealAmount - 1
                                    })
                                    message.destroy(`Q${index}`)
                                    const ele = document.getElementsByClassName(`Q${index - 1}`)[0]
                                    if (ele) {
                                        const style = ele?.getAttribute("style")
                                        ele?.scrollIntoView({
                                            behavior: 'smooth'
                                        })
                                        ele?.setAttribute("style", `${style}border:1px solid red;`)
                                        setTimeout(() => {
                                            ele?.setAttribute("style", `${style}`)
                                        }, 2000)
                                    } else {
                                        message.error({
                                            duration: 0.5,
                                            content: "目标不存在"
                                        })
                                    }
                                }
                            })
                        }
                        if (typeof score === "number") {
                            newQuestion.score = score
                        } else {
                            if (Number.isInteger(parseInt(score, 10))) {
                                newQuestion.score = parseInt(score, 10)
                            } else {
                                newQuestion.score = 0
                            }
                        }
                        newQuestionList.push(newQuestion)
                        break;
                    }
                    case '多选题': {
                        successAmount += 1
                        newQuestion = {
                            type: "multipleChoice",
                            id: `${new Date().getTime() + index}`,
                            questionContext,
                        }
                        let optionList = []
                        if (typeof options === "string") {
                            optionList = options.split("\n")
                        } else {
                            optionList = `${options}`
                        }
                        console.log(optionList)
                        newQuestion.options = optionList
                        const optionLength = optionList.length
                        const reg = new RegExp(`[A-${String.fromCharCode(65 + optionLength - 1)}]`, "g")
                        let flag = true
                        const trueAnswerList = []
                        if (typeof trueAnswer === "string") {
                            const tempTrueAnswerList = trueAnswer.split("\n")
                            tempTrueAnswerList.forEach((answer) => {
                                if (answer.length === 1) {
                                    if (reg.test(answer)) {
                                        console.log(reg, answer, reg.test(answer))
                                        trueAnswerList.push(answer)
                                    } else {
                                        flag = false
                                    }
                                } else {
                                    flag = false
                                }
                            })
                        } else {
                            flag = false
                        }
                        newQuestion.trueAnswer = trueAnswerList
                        if (flag === false) {
                            this.setState({
                                dealAmount: this.state.dealAmount + 1
                            })
                            const index = preLength + successAmount
                            message.warn({
                                key: `Q${index}`,
                                duration: 0,
                                content: `第${index}题参考答案不符合规范，已重置，点击查看`,
                                onClick: () => {
                                    this.setState({
                                        dealAmount: this.state.dealAmount - 1
                                    })
                                    message.destroy(`Q${index}`)
                                    const ele = document.getElementsByClassName(`Q${index - 1}`)[0]
                                    if (ele) {
                                        const style = ele.getAttribute("style")
                                        ele.scrollIntoView({
                                            behavior: 'smooth'
                                        })
                                        ele.setAttribute("style", `${style}border:1px solid red;`)
                                        setTimeout(() => {
                                            ele.setAttribute("style", `${style}`)
                                        }, 2000)
                                    } else {
                                        message.error({
                                            duration: 0.5,
                                            content: "目标不存在"
                                        })
                                    }
                                }
                            })
                        }
                        if (typeof score === "number") {
                            newQuestion.score = score
                        } else {
                            if (Number.isInteger(parseInt(score, 10))) {
                                newQuestion.score = parseInt(score, 10)
                            } else {
                                newQuestion.score = 0
                            }
                        }
                        newQuestionList.push(newQuestion)
                        break;
                    }
                    case '填空题': {
                        let flag = true
                        successAmount += 1
                        newQuestion = {
                            type: "fillInBlank",
                            id: `${new Date().getTime() + index}`,
                            questionContext,
                        }
                        let trueAnswerAmount = 0
                        if (typeof questionContext === "string") {
                            trueAnswerAmount = questionContext.split("[____]").length - 1
                        } else {
                            trueAnswerAmount = 1
                        }
                        let trueAnswerList = []
                        if (typeof trueAnswer === "string") {
                            trueAnswerList = trueAnswer.split("\n")
                            console.log(trueAnswerList)
                            if (trueAnswerList.length !== trueAnswerAmount) {
                                trueAnswerList = trueAnswerList.slice(0, trueAnswerAmount)
                                flag = false
                            }
                        } else {
                            trueAnswerList = `${trueAnswer}`
                        }
                        newQuestion.trueAnswer = trueAnswerList
                        if (flag === false) {
                            this.setState({
                                dealAmount: this.state.dealAmount + 1
                            })
                            const index = preLength + successAmount
                            message.warn({
                                key: `Q${index}`,
                                duration: 0,
                                content: `第${index}题参考答案不符合规范，已重置，点击查看`,
                                onClick: () => {
                                    this.setState({
                                        dealAmount: this.state.dealAmount - 1
                                    })
                                    message.destroy(`Q${index}`)
                                    const ele = document.getElementsByClassName(`Q${index - 1}`)[0]
                                    if (ele) {
                                        const style = ele.getAttribute("style")
                                        ele.scrollIntoView({
                                            behavior: 'smooth'
                                        })
                                        ele.setAttribute("style", `${style}border:1px solid red;`)
                                        setTimeout(() => {
                                            ele.setAttribute("style", `${style}`)
                                        }, 2000)
                                    } else {
                                        message.error({
                                            duration: 0.5,
                                            content: "目标不存在"
                                        })
                                    }
                                }
                            })
                        }
                        if (typeof score === "number") {
                            newQuestion.score = score
                        } else {
                            if (Number.isInteger(parseInt(score, 10))) {
                                newQuestion.score = parseInt(score, 10)
                            } else {
                                newQuestion.score = 0
                            }
                        }
                        newQuestionList.push(newQuestion)
                        break;
                    }
                    default: {
                        errorAmount += 1
                        message.warn(`已忽略不支持的题型：${type},位于第${index + 2}行`)
                        break;
                    }
                }
            })
            this.setState({
                questionList: [
                    ...this.state.questionList,
                    ...newQuestionList,
                ]
            }, () => {
                console.log(this.state.questionList)
            })
            document.getElementById("uploadFile").value = ""
        } else {
            message.error("出错了")
        }
    }

    render() {
        const { questionList } = this.state
        return <div className='middle'>
            {questionList.map((question, index) => {
                const { type, score, id } = question
                switch (type) {
                    case 'singleChoice': {
                        return <BaseTemplate className={`Q${index}`} key={id} type={type} score={score} index={index} onChange={({ type, score }) => {
                            this.changeType(type, score, index)
                        }} deleted={() => {
                            this.deleted(index)
                        }}
                            canDel={!this.state.dealAmount <= 0} >
                            <AddSingleChoice question={question} save={(nextQuestion) => {
                                console.log(nextQuestion)
                                this.save(nextQuestion, index)
                            }} />
                        </BaseTemplate>
                    }
                    case 'multipleChoice': {
                        return <BaseTemplate className={`Q${index}`} key={id} type={type} score={score} index={index} onChange={({ type, score }) => {
                            this.changeType(type, score, index)
                        }} deleted={() => {
                            this.deleted(index)
                        }}
                            canDel={!this.state.dealAmount <= 0}>
                            <AddMultipleChoice question={question} save={(nextQuestion) => {
                                this.save(nextQuestion, index)
                            }} />
                        </BaseTemplate>
                    }
                    case 'fillInBlank': {
                        return <BaseTemplate className={`Q${index}`} key={id} type={type} score={score} index={index} onChange={({ type, score }) => {
                            this.changeType(type, score, index)
                        }} deleted={() => {
                            this.deleted(index)
                        }}
                            canDel={!this.state.dealAmount <= 0}>
                            <AddFillInBlank question={question} save={(nextQuestion) => {
                                this.save(nextQuestion, index)
                            }} />
                        </BaseTemplate>
                    }
                    default: {
                        return null
                    }
                }
            })}
            <div style={{ display: 'flex', justifyContent: 'space-around', margin: '16px 0px 16px 0px' }}>
                <Button type='primary' style={{ width: '200px' }} onClick={() => {
                    this.setState({
                        questionList: [
                            ...questionList,
                            {
                                type: 'singleChoice',
                                id: `${new Date().getTime()}`,
                                questionContext: '',
                                trueAnswer: 'A',
                                options: [""],
                                score: 0
                            },
                        ]
                    }, () => {
                        console.log(this.state.questionList)
                    })
                }}>添加题目</Button>

                <Button
                    style={{
                        width: '200px',
                        padding: 0,
                        textAlign: 'center',
                        lineHeight: '100%',
                    }}>
                    <input
                        type='file'
                        style={{
                            position: 'relative',
                            display: 'inline-block',
                            opacity: 0,
                            width: '100%',
                            height: '100%',
                            zIndex: 1,
                        }}
                        accept='.xls,.xlsx'
                        id='uploadFile'
                        onChange={async () => {
                            try {
                                const uploadFile = document.getElementById(
                                    'uploadFile',
                                );
                                const file = uploadFile.files[0];
                                if (file) {
                                    const fileName = file.name.split('.');
                                    const fileType = fileName[fileName.length - 1];
                                    if (fileType === 'xls' || fileType === 'xlsx') {
                                        const fReader = new FileReader();
                                        fReader.readAsBinaryString(file);
                                        fReader.onload = (e) => {
                                            const dataList = [];
                                            const result = XLSX.read(e.target.result, {
                                                type: 'binary',
                                            });
                                            const { Sheets } = result;
                                            const sheetNameList = Object.keys(Sheets);
                                            sheetNameList.forEach((name) => {
                                                const sheet = Sheets[name];
                                                const positionList = Object.keys(sheet);
                                                positionList.forEach((position) => {
                                                    if (position !== '!ref') {
                                                        const value = sheet[position].v;
                                                        let row = undefined;
                                                        let col = undefined;
                                                        for (
                                                            let index = 0;
                                                            index < position.length;
                                                            index += 1
                                                        ) {
                                                            if (
                                                                Number.isInteger(
                                                                    parseInt(
                                                                        position[index],
                                                                    ),
                                                                )
                                                            ) {
                                                                row = parseInt(
                                                                    position.slice(
                                                                        index,
                                                                    ),
                                                                    10,
                                                                );
                                                                col = position.slice(
                                                                    0,
                                                                    index,
                                                                );
                                                                break;
                                                            }
                                                        }
                                                        if (row && row !== 1) {
                                                            if (!dataList[row - 2]) {
                                                                dataList[row - 2] = {};
                                                            }
                                                            const dataIndex =
                                                                dataIndexMap[
                                                                sheet[`${col}1`].v
                                                                ];
                                                            if (dataIndex) {
                                                                dataList[row - 2][
                                                                    dataIndex
                                                                ] = `${value}`;
                                                            }
                                                        }
                                                    }
                                                });
                                            });
                                            this.importFromExcel(dataList);
                                        };
                                    } else {
                                        message.error('不是支持的文件类型');
                                    }
                                }
                            } catch (e) {
                                console.error(e);
                                message.error('出错了');
                            }
                        }}
                    />
                    <span
                        style={{
                            height: '100%',
                            width: '100%',
                            lineHeight: '30px',
                            textAlign: 'center',
                            position: 'relative',
                            left: '-100%',
                        }}>
                        表格导入
					</span>
                </Button>


                <Spin spinning={this.props.loading}>
                    <Button
                        type='default'
                        style={{ width: '200px' }}
                        onClick={() => {
                            if (this.checkQuestion(this.state.questionList)) {
                                this.props.onRelease(this.state.questionList)
                            }
                        }}>发布考试</Button>
                </Spin>
            </div>
        </div>
    }
}

export default Index
